//! # 认证服务构建器
//!
//! 提供便捷的认证服务构建功能，支持链式配置。

use std::sync::Arc;
use std::collections::HashMap;
use rustcloud_security::prelude::*;
use crate::service::{AuthService, AuthServiceConfig, AuthProviderInfo, SessionConfig, SecurityConfig};

/// 认证服务构建器
pub struct AuthServiceBuilder {
    config: AuthServiceConfig,
    providers: HashMap<String, Arc<dyn AuthProvider>>,
    permission_checker: Option<Arc<dyn PermissionChecker>>,
    session_manager: Option<Arc<dyn SessionManager>>,
    #[cfg(feature = "audit")]
    auditor: Option<Arc<dyn crate::audit::SecurityAuditor>>,
}

impl AuthServiceBuilder {
    /// 创建新的构建器
    pub fn new() -> Self {
        Self {
            config: AuthServiceConfig::default(),
            providers: HashMap::new(),
            permission_checker: None,
            session_manager: None,
            #[cfg(feature = "audit")]
            auditor: None,
        }
    }

    /// 使用自定义配置创建构建器
    pub fn with_config(config: AuthServiceConfig) -> Self {
        Self {
            config,
            providers: HashMap::new(),
            permission_checker: None,
            session_manager: None,
            #[cfg(feature = "audit")]
            auditor: None,
        }
    }

    /// 添加认证提供者
    pub fn add_provider(
        mut self,
        name: String,
        provider: Arc<dyn AuthProvider>,
    ) -> Self {
        self.providers.insert(name.clone(), provider);
        
        // 如果配置中没有对应的提供者信息，则添加
        if !self.config.providers.iter().any(|p| p.name == name) {
            self.config.providers.push(AuthProviderInfo {
                name: name.clone(),
                provider_type: AuthProviderType::Custom(name),
                priority: 0,
                enabled: true,
            });
        }
        
        self
    }

    /// 使用 Gateway 集成的认证提供者
    #[cfg(feature = "gateway-integration")]
    pub fn with_gateway_integration(self) -> AuthResult<Self> {
        use crate::providers::{JwtProvider, ApiKeyProvider, JwtConfig, ApiKeyConfig};
        
        // 添加默认的 JWT 提供者
        let jwt_config = JwtConfig::default();
        let jwt_provider = Arc::new(JwtProvider::new(jwt_config).await
            .map_err(|e| AuthError::ConfigurationError(format!("Failed to create JWT provider: {}", e)))?);
        
        // 添加默认的 API Key 提供者
        let api_key_config = ApiKeyConfig::default();
        let api_key_provider = Arc::new(ApiKeyProvider::with_config(api_key_config));
        
        Ok(self
            .add_provider("jwt".to_string(), jwt_provider)
            .add_provider("api_key".to_string(), api_key_provider)
            .with_default_provider("jwt".to_string()))
    }

    /// 添加 JWT 认证提供者
    #[cfg(feature = "gateway-integration")]
    pub async fn with_jwt_provider(self, config: crate::providers::JwtConfig) -> AuthResult<Self> {
        use crate::providers::JwtProvider;
        let provider = Arc::new(JwtProvider::new(config).await
            .map_err(|e| AuthError::ConfigurationError(format!("Failed to create JWT provider: {}", e)))?);
        Ok(self.add_provider("jwt".to_string(), provider))
    }

    /// 添加 API Key 认证提供者
    #[cfg(feature = "gateway-integration")]
    pub fn with_api_key_provider(self, config: crate::providers::ApiKeyConfig) -> Self {
        use crate::providers::ApiKeyProvider;
        let provider = Arc::new(ApiKeyProvider::with_config(config));
        self.add_provider("api_key".to_string(), provider)
    }

    /// 添加 OAuth2 认证提供者
    #[cfg(feature = "oauth2")]
    pub fn with_oauth2_provider(self, config: crate::providers::oauth2::OAuth2Config) -> AuthResult<Self> {
        let provider = Arc::new(crate::providers::oauth2::OAuth2Provider::new(config)?);
        Ok(self.add_provider("oauth2".to_string(), provider))
    }

    /// 设置默认认证提供者
    pub fn with_default_provider(mut self, provider_name: String) -> Self {
        self.config.default_provider = provider_name;
        self
    }

    /// 设置权限检查器
    pub fn with_permission_checker(mut self, checker: Arc<dyn PermissionChecker>) -> Self {
        self.permission_checker = Some(checker);
        self
    }

    /// 启用RBAC权限控制
    #[cfg(feature = "rbac")]
    pub fn with_rbac_enabled(self) -> AuthResult<Self> {
        let role_manager = Arc::new(crate::rbac::RoleManager::new());
        let permission_checker = Arc::new(crate::rbac::RbacPermissionChecker::new(role_manager));
        Ok(self.with_permission_checker(permission_checker))
    }

    /// 设置会话管理器
    pub fn with_session_manager(mut self, manager: Arc<dyn SessionManager>) -> Self {
        self.session_manager = Some(manager);
        self
    }

    /// 启用内存会话管理
    pub fn with_memory_session_manager(self) -> Self {
        let manager = Arc::new(MemorySessionManager::new(self.config.session_config.clone()));
        self.with_session_manager(manager)
    }

    /// 设置安全审计器
    #[cfg(feature = "audit")]
    pub fn with_auditor(mut self, auditor: Arc<dyn crate::audit::SecurityAuditor>) -> Self {
        self.auditor = Some(auditor);
        self
    }

    /// 启用审计功能
    #[cfg(feature = "audit")]
    pub fn with_audit_enabled(self) -> AuthResult<Self> {
        let auditor = Arc::new(crate::audit::DefaultSecurityAuditor::new()?);
        Ok(self.with_auditor(auditor))
    }

    /// 设置会话配置
    pub fn with_session_config(mut self, config: SessionConfig) -> Self {
        self.config.session_config = config;
        self
    }

    /// 设置安全配置
    pub fn with_security_config(mut self, config: SecurityConfig) -> Self {
        self.config.security_config = config;
        self
    }

    /// 启用权限检查
    pub fn with_permission_enabled(mut self, enabled: bool) -> Self {
        self.config.permission_enabled = enabled;
        self
    }

    /// 构建认证服务
    pub async fn build(self) -> AuthResult<AuthService> {
        // 验证必要的组件
        if self.providers.is_empty() {
            return Err(AuthError::ConfigurationError("No authentication providers configured".to_string()));
        }

        // 检查默认提供者是否存在
        if !self.providers.contains_key(&self.config.default_provider) {
            return Err(AuthError::ConfigurationError(
                format!("Default provider '{}' not found", self.config.default_provider)
            ));
        }

        // 使用新的统一权限检查器（如果未设置）
        let permission_checker = self.permission_checker
            .unwrap_or_else(|| Arc::new(SimplePermissionChecker::new()));

        // 创建认证服务
        let mut auth_service = AuthService::new(
            self.config,
            self.providers,
            permission_checker,
        );

        // 设置可选组件
        if let Some(session_manager) = self.session_manager {
            auth_service = auth_service.with_session_manager(session_manager);
        }

        #[cfg(feature = "audit")]
        if let Some(auditor) = self.auditor {
            auth_service = auth_service.with_auditor(auditor);
        }

        Ok(auth_service)
    }
}

impl Default for AuthServiceBuilder {
    fn default() -> Self {
        Self::new()
    }
}

// 使用新的统一权限检查器替代本地实现
// 原有的 DefaultPermissionChecker 已被移除，现在使用 rustcloud-core 中的实现
pub type DefaultPermissionChecker = rustcloud_core::auth::CommonPermissionChecker;

/// 内存会话管理器实现
pub struct MemorySessionManager {
    sessions: Arc<std::sync::RwLock<HashMap<String, (Principal, std::time::SystemTime)>>>,
    config: SessionConfig,
}

impl MemorySessionManager {
    pub fn new(config: SessionConfig) -> Self {
        Self {
            sessions: Arc::new(std::sync::RwLock::new(HashMap::new())),
            config,
        }
    }

    /// 清理过期会话
    async fn cleanup_expired_sessions(&self) {
        let now = std::time::SystemTime::now();
        let timeout = std::time::Duration::from_secs(self.config.timeout_seconds);

        if let Ok(mut sessions) = self.sessions.write() {
            sessions.retain(|_, (_, created_at)| {
                now.duration_since(*created_at)
                    .map(|duration| duration < timeout)
                    .unwrap_or(false)
            });
        }
    }
}

#[async_trait]
impl SessionManager for MemorySessionManager {
    async fn create_session(&self, principal: &Principal) -> AuthResult<String> {
        if !self.config.enabled {
            return Err(AuthError::UnsupportedOperation("Session management disabled".to_string()));
        }

        self.cleanup_expired_sessions().await;

        let session_id = uuid::Uuid::new_v4().to_string();
        let now = std::time::SystemTime::now();

        if let Ok(mut sessions) = self.sessions.write() {
            // 检查用户的并发会话数
            let user_sessions: Vec<_> = sessions
                .iter()
                .filter(|(_, (p, _))| p.id == principal.id)
                .map(|(k, _)| k.clone())
                .collect();

            if user_sessions.len() >= self.config.max_concurrent_sessions as usize {
                // 删除最旧的会话
                if let Some(oldest_session) = user_sessions.first() {
                    sessions.remove(oldest_session);
                }
            }

            sessions.insert(session_id.clone(), (principal.clone(), now));
        } else {
            return Err(AuthError::InternalError("Failed to acquire sessions lock".to_string()));
        }

        Ok(session_id)
    }

    async fn get_session(&self, session_id: &str) -> AuthResult<Principal> {
        self.cleanup_expired_sessions().await;

        if let Ok(sessions) = self.sessions.read() {
            if let Some((principal, _)) = sessions.get(session_id) {
                Ok(principal.clone())
            } else {
                Err(AuthError::InvalidSession("Session not found".to_string()))
            }
        } else {
            Err(AuthError::InternalError("Failed to acquire sessions lock".to_string()))
        }
    }

    async fn update_session(&self, session_id: &str, principal: &Principal) -> AuthResult<()> {
        let now = std::time::SystemTime::now();

        if let Ok(mut sessions) = self.sessions.write() {
            if sessions.contains_key(session_id) {
                sessions.insert(session_id.to_string(), (principal.clone(), now));
                Ok(())
            } else {
                Err(AuthError::InvalidSession("Session not found".to_string()))
            }
        } else {
            Err(AuthError::InternalError("Failed to acquire sessions lock".to_string()))
        }
    }

    async fn delete_session(&self, session_id: &str) -> AuthResult<()> {
        if let Ok(mut sessions) = self.sessions.write() {
            sessions.remove(session_id);
            Ok(())
        } else {
            Err(AuthError::InternalError("Failed to acquire sessions lock".to_string()))
        }
    }

    async fn delete_user_sessions(&self, user_id: &str) -> AuthResult<()> {
        if let Ok(mut sessions) = self.sessions.write() {
            sessions.retain(|_, (principal, _)| principal.id != user_id);
            Ok(())
        } else {
            Err(AuthError::InternalError("Failed to acquire sessions lock".to_string()))
        }
    }

    async fn is_session_valid(&self, session_id: &str) -> AuthResult<bool> {
        self.cleanup_expired_sessions().await;

        if let Ok(sessions) = self.sessions.read() {
            Ok(sessions.contains_key(session_id))
        } else {
            Err(AuthError::InternalError("Failed to acquire sessions lock".to_string()))
        }
    }

    async fn extend_session(&self, session_id: &str, _extend_by: std::time::Duration) -> AuthResult<()> {
        // 在内存实现中，每次访问都会更新时间戳
        let principal = {
            let sessions = self.sessions.read().map_err(|_| AuthError::InternalError("Failed to acquire sessions lock".to_string()))?;
            if let Some((principal, _)) = sessions.get(session_id) {
                principal.clone()
            } else {
                return Err(AuthError::InvalidSession("Session not found".to_string()));
            }
        };
        
        self.update_session(session_id, &principal).await
    }
}

/// 简单权限检查器实现
pub struct SimplePermissionChecker;

impl SimplePermissionChecker {
    pub fn new() -> Self {
        Self
    }
}

#[async_trait]
impl PermissionChecker for SimplePermissionChecker {
    async fn check(&self, principal: &Principal, permission: &str) -> AuthResult<bool> {
        // 管理员拥有所有权限
        if principal.principal_type == PrincipalType::Admin {
            return Ok(true);
        }
        
        // 检查用户权限列表
        Ok(principal.permissions.contains(permission))
    }
    
    async fn check_resource(&self, principal: &Principal, resource: &Resource) -> AuthResult<bool> {
        // 管理员拥有所有权限
        if principal.principal_type == PrincipalType::Admin {
            return Ok(true);
        }
        
        // 基于资源生成权限字符串
        let permission = format!("{}:{}:{}", resource.service, resource.method.to_lowercase(), resource.path);
        self.check(principal, &permission).await
    }
    
    async fn check_multiple(&self, principal: &Principal, permissions: &[&str]) -> AuthResult<Vec<bool>> {
        let mut results = Vec::new();
        for permission in permissions {
            results.push(self.check(principal, permission).await?);
        }
        Ok(results)
    }
    
    async fn check_any(&self, principal: &Principal, permissions: &[&str]) -> AuthResult<bool> {
        for permission in permissions {
            if self.check(principal, permission).await? {
                return Ok(true);
            }
        }
        Ok(false)
    }
    
    async fn check_all(&self, principal: &Principal, permissions: &[&str]) -> AuthResult<bool> {
        for permission in permissions {
            if !self.check(principal, permission).await? {
                return Ok(false);
            }
        }
        Ok(true)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_auth_service_builder() {
        let builder = AuthServiceBuilder::new()
            .with_default_provider("test".to_string())
            .with_permission_enabled(true);

        // 需要添加至少一个提供者才能构建
        // 这里我们只测试构建器的配置功能
        assert_eq!(builder.config.default_provider, "test");
        assert!(builder.config.permission_enabled);
    }

    #[tokio::test]
    async fn test_default_permission_checker() {
        let checker = DefaultPermissionChecker::new();
        
        let admin_principal = Principal::new(
            "admin".to_string(),
            "Admin User".to_string(),
            PrincipalType::Admin,
        );

        let user_principal = Principal::new(
            "user".to_string(),
            "Regular User".to_string(),
            PrincipalType::User,
        ).add_permission("read:posts".to_string());

        // 管理员应该有所有权限
        assert!(checker.check(&admin_principal, "any:permission").await.unwrap());

        // 普通用户应该只有特定权限
        assert!(checker.check(&user_principal, "read:posts").await.unwrap());
        assert!(!checker.check(&user_principal, "write:posts").await.unwrap());
    }

    #[tokio::test]
    async fn test_memory_session_manager() {
        let config = SessionConfig {
            timeout_seconds: 60,
            enabled: true,
            max_concurrent_sessions: 2,
        };
        
        let manager = MemorySessionManager::new(config);
        let principal = Principal::new(
            "test_user".to_string(),
            "Test User".to_string(),
            PrincipalType::User,
        );

        // 创建会话
        let session_id = manager.create_session(&principal).await.unwrap();
        assert!(!session_id.is_empty());

        // 获取会话
        let retrieved_principal = manager.get_session(&session_id).await.unwrap();
        assert_eq!(retrieved_principal.id, principal.id);

        // 验证会话
        assert!(manager.is_session_valid(&session_id).await.unwrap());

        // 删除会话
        manager.delete_session(&session_id).await.unwrap();
        assert!(!manager.is_session_valid(&session_id).await.unwrap());
    }
}